package compiler.lexical;

import compiler.syntax.sym;
import compiler.lexical.Token;
import es.uned.lsi.compiler.lexical.ScannerIF;
import es.uned.lsi.compiler.lexical.LexicalError;
import es.uned.lsi.compiler.lexical.LexicalErrorManager;

// incluir aqui, si es necesario otras importaciones

%%
 
%public
%class Scanner
%char
%line
%column
%cup

%implements ScannerIF
%scanerror LexicalError

// incluir aqui, si es necesario otras directivas


SALTODELINEA = \r\n
COMENTARIO = --.*\r\n
DIGITO = [0-9]
CARACTER = [a-zA-Z]
CONSTANTENUM = [1-9]{DIGITO}*
CONSTANTECADENA = \".*\"
IDENTIFICADOR = {CARACTER}({CARACTER}|{DIGITO})*



%{
  LexicalErrorManager lexicalErrorManager = new LexicalErrorManager ();
  private int commentCount = 0;
%}  
  
%%

<YYINITIAL> 
{
           			       
    "+"                {  
                           Token token = new Token (sym.PLUS);
                           token.setLine (yyline + 1);
                           token.setColumn (yycolumn + 1);
                           token.setLexema (yytext ());
           			       return token;
                        }
                 
    
      // incluir aqui el resto de las reglas patron - accion
    " "|\t          {/* Ignora espacios en blanco y tabulaciones */ }
    {SALTODELINEA}	{/* Ignora SALTO DE LINEA */}
    {COMENTARIO}	{/* Ignora comentarios */}
    {CONSTANTENUM}  {return new Token (sym.CONSTANTENUM,yyline+1,yycolumn+1, yytext());}
    {CONSTANTECADENA}  {return new Token (sym.CONSTANTECADENA,yyline+1,yycolumn+1, yytext());}
    {IDENTIFICADOR} {return new Token (sym.IDENTIFICADOR,yyline+1,yycolumn+1, yytext());}
      
      //Operadores
	    "-"			{return new Token (sym.MINUS,yyline+1,yycolumn+1, yytext());}
	    "<"			{return new Token (sym.MENORQUE,yyline+1,yycolumn+1, yytext());}
	    ">"			{return new Token (sym.MAYORQUE,yyline+1,yycolumn+1, yytext());}
	    "="			{return new Token (sym.IGUALQUE,yyline+1,yycolumn+1, yytext());}
	    "/="		{return new Token (sym.DISTINTO,yyline+1,yycolumn+1, yytext());}
	    "and"		{return new Token (sym.AND,yyline+1,yycolumn+1, yytext());}
	    "or"		{return new Token (sym.OR,yyline+1,yycolumn+1, yytext());}
	    ":="		{return new Token (sym.ASIGNA,yyline+1,yycolumn+1, yytext());}
	    "."			{return new Token (sym.CAMPO,yyline+1,yycolumn+1, yytext());}
	    
	  //palabras reservadas
		and			{return new Token (sym.AND,yyline+1,yycolumn+1, yytext());}
		array		{return new Token (sym.ARRAY,yyline+1,yycolumn+1, yytext());}
		begin		{return new Token (sym.BEGIN,yyline+1,yycolumn+1, yytext());}
	    Boolean		{return new Token (sym.BOOLEAN,yyline+1,yycolumn+1, yytext());}
	    constant	{return new Token (sym.CONSTANT,yyline+1,yycolumn+1, yytext());}
	    else		{return new Token (sym.ELSE,yyline+1,yycolumn+1, yytext());}
	    end			{return new Token (sym.END,yyline+1,yycolumn+1, yytext());}
	    False		{return new Token (sym.FALSE,yyline+1,yycolumn+1, yytext());}
	    for			{return new Token (sym.FOR,yyline+1,yycolumn+1, yytext());}
	    function	{return new Token (sym.FUNCTION,yyline+1,yycolumn+1, yytext());}
	    if			{return new Token (sym.IF,yyline+1,yycolumn+1, yytext());}
	    in			{return new Token (sym.IN,yyline+1,yycolumn+1, yytext());}
	    Integer		{return new Token (sym.INTEGER,yyline+1,yycolumn+1, yytext());}
	    is			{return new Token (sym.IS,yyline+1,yycolumn+1, yytext());}
	    loop		{return new Token (sym.LOOP,yyline+1,yycolumn+1, yytext());}
	    of			{return new Token (sym.OF,yyline+1,yycolumn+1, yytext());}
	  	or			{return new Token (sym.OR,yyline+1,yycolumn+1, yytext());}
	  	out			{return new Token (sym.OUT,yyline+1,yycolumn+1, yytext());}
	  	procedure	{return new Token (sym.PROCEDURE,yyline+1,yycolumn+1, yytext());}		
	    Put_line	{return new Token (sym.PUT_LINE,yyline+1,yycolumn+1, yytext());}
	    record		{return new Token (sym.RECORD,yyline+1,yycolumn+1, yytext());}
	    return		{return new Token (sym.RETURN,yyline+1,yycolumn+1, yytext());}
	    then		{return new Token (sym.THEN,yyline+1,yycolumn+1, yytext());}
	    True		{return new Token (sym.TRUE,yyline+1,yycolumn+1, yytext());}
	    type		{return new Token (sym.TYPE,yyline+1,yycolumn+1, yytext());}
	    while		{return new Token (sym.WHILE,yyline+1,yycolumn+1, yytext());} 
    
    //Delimitadores
	    "("			{return new Token (sym.PARENTIZ,yyline+1,yycolumn+1, yytext());}
	    ")"			{return new Token (sym.PARENTDE,yyline+1,yycolumn+1, yytext());}
	    ".."		{return new Token (sym.RANGO,yyline+1,yycolumn+1, yytext());}
	    "--"		{return new Token (sym.COMENT,yyline+1,yycolumn+1, yytext());}
	    ","			{return new Token (sym.LISTA,yyline+1,yycolumn+1, yytext());}
	    ";"			{return new Token (sym.FIN,yyline+1,yycolumn+1, yytext());}
	    ":"			{return new Token (sym.TYPO,yyline+1,yycolumn+1, yytext());}
    
       
    
    // error en caso de coincidir con ning�n patr�n
	[^]     
                        {                                               
                           LexicalError error = new LexicalError ();
                           error.setLine (yyline + 1);
                           error.setColumn (yycolumn + 1);
                           error.setLexema (yytext ());
                           lexicalErrorManager.lexicalError (error);
                        }
    
}


                         


